#!/bin/bash
#========================================================================
# Author: YSLin
# Email: 
# File Name: find.sh
# Description: 
#   
# Edit History: 
#   2011-01-18    File created.
#========================================================================

##########################################
#不要執行這個檔案會刪掉檔案喔!!
##########################################

#If the command given is not a utility that exists as a separate disk file, type tells you whether it is one of the
#following:
#  A shell built-in command
#  A shell keyword or reserved word
#  An alias
type true vi case ulimit history

#刪除所有當下的目錄
find -type d | xargs rm -rf
#exec 是找到之後要執行的指令
#{} 代表找到的檔案
#; 是指令 exec 的終止符號，要用 \ 進行跳脫(excape)的動作
find . -type d -exec rmdir  {} \;

#刪除除了file的檔案之外
ls !(file)|xargs rm

#刪除除了file1, file2,... fileN之外的檔案
ls !(file1|file2|...|fileN)|xargs rm

#刪除除了file1,file2之外的檔案
rm !(file1|file2)

#刪除除了file1, file2之外的檔案
find ! /( -name "file1" -o -name "file2" /) -exec rm {} /;

#找所有apk檔案並且用apktoll解開
find . -name "*.apk" -exec ../../apktool d {} \;

#找出所有AndroidManifest.xml檔案內容
find . -name AndroidManifest.xml -exec echo {} \; -exec cat {} \;  > test 

#找出所有log檔,並且一個一個作指令處理或呼叫函式, -exec 中沒辦法呼叫函式/執行指令替換(`command`), 可以呼叫其他的shell script
for file in `find . -name '*.log' -print 2>/dev/null`
do
	echo $file
	echo "Dirname:"
	dirname $file
done

#想要在A目錄下把屬性為檔案的全部檔案,移到B目錄但不包含A目錄下的子目錄內的檔案
find /A -maxdepth 1 -type f -exec mv {} /B \;

#搜尋 /etc 該層目錄 (不包含其下子目錄) 內所有的一般檔案
find /etc -type f -maxdepth 1

#找目錄下不包含.pl的檔案、目錄
find . -! -name "*.pl" -name '*' -print
find . -not -name "*.pl" -name '*' -print

#找目錄下不包含.svn的檔案、目錄
find . -not -wholename  '*.svn*' -print
find .  ! -wholename  '*.svn*' -print 

#找以abc开头，但不包含“.”的文件的方法
find . -name "abc*" ! -name "*.*" -print  #第二个 -name前的 !　号表示 -not，　与-not的意义是相同的
find . -regex '.*/abc[^.]*'    # .*/　表示在当前目录及下及目录中找, [^.]* 表示abc后匹配任意字符，除了.
find . -name "*.*" -o -name "abc*" -print  
#-o 是　or 的意思，也就是或, 猛的看起来好像是说找到所有含有. 或者以abc开头的,其实不然,这两个-name构成了这样形式的表达式,
#Exp1 or Exp2
#如果Exp1 为真的话，就不会再判断Exp2
#如果Exp1为假，才执行Exp2，非常类似于C语言中的 " || "　符号
#所以，如果匹配到有.的文件名，则不会执行后面的了，所以-print此时不会打印

#砍掉PATH下所有.svn目錄, PATH 再自行換成那個路徑即可. :), svn 有 export 的參數可以用, 使用 export 就不會有 .svn 的目錄:, svn export http://HOSTNAME/SVN_PATH (跟 checkout 參數類同)
find PATH -type d -name '.svn' -exec rm -rf {} \;

#找尋哪些目錄不包含某特定檔案
for dir in `find . -type d -maxdepth 1`
do
    if [ ! -e $dir/AndroidManifest.xml ] ; then
        echo $dir;
    fi                                                                                                                                                                                       
done

#找尋當下目錄的檔案副檔名為.apk, 不會有find造成有空白字元的檔案名稱會對不上的問題
for file in *.apk  
do
	echo "$file";
done

#找尋當下,第一層次目錄,第二、第三層次目錄下的.apk檔案
for apk in *.apk */*.apk */*/*.apk */*/*/*.apk
do
	#1.apk, a/2.apk, a/b/3.apk, a/b/c/4.apk 
	echo $apk
done

#==============================================================================
# 避免檔名有空白的問題的方法
#==============================================================================
#關掉用space作為分隔,避免for loop parse的問題
IFS=$(echo -en "\n\b")
for file in `find . -name "*.apk"`
do
	grep -rn "keyword" $file

	if [ $? -eq '0' ] ; then
		echo "find keyword in [$file]"
	fi
done

#To process the output of find with a command, try as follows:
#man bash, then find read command as below
#read [-ers] [-a aname] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]
find . -print0 | while read -d $'\0' file
do
  echo -v "$file"
done

#Try to copy files to /tmp with spaces in a filename using find command and shell pipes
find . -print0 | while read -d $'\0' file; do cp -v "$file" /tmp; done

function findDir(){
	DIR="$1"

	# failsafe - fall back to current directory
	[ "$DIR" == "" ] && DIR="." 

	# save and change IFS
	OLDIFS=$IFS
	IFS=$'\n' 

	# read all file name into an array
	fileArray=($(find $DIR -type f))

	# restore it
	IFS=$OLDIFS

	# get length of an array
	tLen=${#fileArray[@]}

	# use for loop read all filenames
	for (( i=0; i<${tLen}; i++ ));
	do
		echo "${fileArray[$i]}"
	done
}

#==============================================================================
# 遞迴查詢所有目錄
#==============================================================================
do_list() {
    # 這個函數是做遞迴處理(自己呼叫自己)的，所以將變數宣告為區域變數
    local dir count
    dir="$1"
    count=0

    #對於使用「${dir}/*」之後顯示出來的所有檔案．資料夾做同樣的處理
    for fn in ${dir}/*; do
    if [ -d "$fn" ]; then   #若是資料夾的話，做遞迴呼叫
        do_list "${fn}"
    fi  
    count=`expr $count + 1` #統計檔案的個數
    done
    echo "${count} ${dir}"
}

do_list $1

